home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Audio / Spectro / Source / SpectrumView.m < prev    next >
Text File  |  1994-05-06  |  7KB  |  280 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "SpectrumView.h"
  5. #import <appkit/appkit.h>
  6. #import <appkit/PrintInfo.h>
  7.  
  8. float back_ground = 0.0/3.0, draw_gray = 3.0/3.0, marker_gray = 1.0/3.0;
  9. float freq_range,amp_range,*last_data;
  10. float lastVertPos,lastHorPos;
  11. int last_length;
  12. BOOL not_first_time;
  13. NXPoint  last_cursor;
  14.  
  15. @implementation SpectrumView
  16.  
  17. - setBackGround: (float) gray
  18. {
  19.     back_ground = gray;
  20.     return self;
  21. }
  22.  
  23. - setDraw: (float) gray
  24. {
  25.     draw_gray = gray;
  26.     return self;
  27. }
  28.  
  29. - setFreqRange: (float) aFreqRange andAmpRange: (float) anAmpRange
  30. {
  31.     freq_range = aFreqRange;
  32.     amp_range = anAmpRange;
  33.     return self;
  34. }
  35.  
  36. - (float) ampRange
  37. {
  38.     return amp_range;
  39. }
  40.  
  41. - drawSpectrum: (int) length array: (float *) f
  42. {
  43.     [self drawSpectrum: length array: f erase: FALSE];
  44.     return self;
  45. }
  46.  
  47. - drawSpectrum: (int) length array: (float *) f erase: (BOOL) erase
  48. {
  49.     int i,incr;
  50.     double xstep,ymax,max=0.0;
  51.     xstep = frame.size.width / length;
  52.     ymax = frame.size.height;
  53.     incr = length / frame.size.width;
  54.     if (last_length!=length) {
  55.         if (last_data) free(last_data);
  56.     last_data = (float *) malloc(4 * length);
  57.     last_length = length;
  58.     }
  59.     [self lockFocus];
  60.     [self setOpaque: TRUE];
  61.     PSsetlinewidth(0.1);
  62.     if (erase)
  63.         PSsetgray(back_ground);
  64.     else
  65.         PSsetgray(draw_gray);
  66.     PSmoveto(0.0,f[0] * ymax);
  67.     last_data[0] = f[0];
  68.     for (i=1;i<length;i++) {
  69.     last_data[i] = f[i];
  70.     if (f[i]>max) max = f[i];
  71.     if (incr==0)    {
  72.         PSlineto((double) i * xstep,max * ymax);
  73.         max = 0.0;    
  74.     }
  75.     else if ((i%incr)==0)    {
  76.         PSlineto((double) i * xstep,max * ymax);
  77.         max = 0.0;
  78.     }
  79.     }
  80.     PSstroke();
  81.     PSflushgraphics();
  82.     [self unlockFocus];
  83.      [[self window] flushWindow];
  84.     last_cursor.x = -1.0;
  85.     return self;
  86. }
  87.  
  88. - placeVerticals: (float) positions;
  89. {
  90.     double xpos,ypos,xdel;
  91.     xpos = frame.size.width * positions;
  92.     xdel = xpos;
  93.     lastVertPos = positions;
  94.     if (xdel<=0) xdel = 1.0;
  95.     ypos = frame.size.height;
  96.     [self lockFocus];
  97.     [self setOpaque: TRUE];
  98.     PSsetlinewidth(0.1);
  99.     PSsetgray(marker_gray);
  100.     while (xpos<=frame.size.width)    {
  101.         PSmoveto(xpos,0.0);
  102.         PSlineto(xpos,ypos);
  103.     xpos += xdel;
  104.     }
  105.     PSstroke();
  106.     PSflushgraphics();
  107.     [self unlockFocus];
  108.     return self;
  109. }
  110.  
  111. - placeHorizontals: (float) heights;
  112. {
  113.     double xpos,ypos,ydel;
  114.     xpos = frame.size.width;
  115.     ypos = frame.size.height * heights;
  116.     ydel = ypos;
  117.     lastHorPos = heights;
  118.     if (ydel<=0) ydel = 1.0;
  119.     [self lockFocus];
  120.     [self setOpaque: TRUE];
  121.     PSsetlinewidth(0.1);
  122.     PSsetgray(marker_gray);
  123.     while (ypos<frame.size.height)    {
  124.         PSmoveto(0.0,ypos);
  125.         PSlineto(xpos,ypos);
  126.     ypos += ydel;
  127.     }
  128.     PSstroke();
  129.     PSflushgraphics();
  130.     [self unlockFocus];
  131.     return self;
  132.  
  133. }
  134.     
  135. - clear
  136. {
  137.     [self lockFocus];
  138.     [self setOpaque: TRUE];
  139.     PSsetgray(back_ground);
  140.     PSrectfill(0.,0.,bounds.size.width,bounds.size.height);
  141.     PSstroke();
  142.     PSflushgraphics();
  143.     [self unlockFocus];
  144.     return self;
  145. }
  146.  
  147. - drawSelf: (NXRect *) r : (int) n 
  148. {
  149.     if (not_first_time)   {
  150.         [self clear];
  151.     [self drawSpectrum: last_length array: last_data erase: FALSE];
  152.     [self placeHorizontals: lastHorPos];
  153.     [self placeVerticals: lastVertPos];
  154.     if (last_cursor.x>0 && last_cursor.x<frame.size.width) [self drawCursor: last_cursor erase: FALSE];
  155.     }
  156.     else    {
  157.        [self clear];
  158.     not_first_time = TRUE;
  159.     }
  160.     
  161. return self;
  162. }
  163.  
  164. #define MOVE_MASK NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK
  165.  
  166. - (BOOL)acceptsFirstMouse
  167. {
  168.   return (YES);
  169. }
  170.  
  171. - mouseDown: (NXEvent *)event
  172. {
  173.     NXPoint currentPosition;
  174.     NXEvent *nextEvent;
  175.     BOOL tracking = TRUE;
  176.     int oldMask,checkMask;
  177.     
  178.     oldMask = [window eventMask];
  179.     checkMask = NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK;
  180.     [window setEventMask: (oldMask | checkMask)];
  181.     
  182.     [self lockFocus];
  183.     
  184.     currentPosition = event->location;
  185.     [self convertPoint:¤tPosition fromView:nil];
  186.     event = [NXApp getNextEvent:MOVE_MASK];
  187.  
  188.     if (last_cursor.x>0 && last_cursor.x<frame.size.width) 
  189.     [self drawCursor: last_cursor erase: TRUE];
  190. //    if (event->type!=NX_MOUSEUPMASK && last_data)    {
  191.     while (tracking) {
  192.         nextEvent = [NXApp getNextEvent: checkMask];
  193.         tracking = (nextEvent->type != NX_MOUSEUP);
  194.         if (tracking)    {
  195.             currentPosition = nextEvent -> location;
  196.         [self convertPoint:¤tPosition fromView:nil];
  197.             if (currentPosition.x>0.0 && currentPosition.x < frame.size.width 
  198.                 && currentPosition.y > 0.0 && currentPosition.y < frame.size.height)    {
  199.             if (last_cursor.x != currentPosition.x)    {
  200.                 [self drawCursor: last_cursor erase: TRUE];
  201.                 [self drawCursor: currentPosition erase: FALSE];
  202.             last_cursor = currentPosition;
  203.             [window flushWindow];
  204.             }
  205.             }
  206.         }
  207.     }
  208. //    }
  209.    [self unlockFocus];
  210.     [window setEventMask:oldMask];
  211.     return self;
  212. }
  213.  
  214. - drawCursor: (NXPoint) point erase: (BOOL) erase
  215. {
  216.     double xpos,ypos1,ypos2,ypos3,min,max;
  217.     int data_position;
  218.     data_position = point.x  / frame.size.width * last_length + 0.5;
  219.     xpos = point.x;
  220.     min = frame.size.height;
  221.     max = 0.0;
  222.     ypos1 = frame.size.height * last_data[data_position - 1];
  223.     ypos2 = frame.size.height * last_data[data_position];
  224.     ypos3 = frame.size.height * last_data[data_position + 1];
  225.     if (ypos1>max) max = ypos1;
  226.     if (ypos2>max) max = ypos2;
  227.     if (ypos3>max) max = ypos3;
  228.     if (ypos1<min) min = ypos1;
  229.     if (ypos2<min) min = ypos2;
  230.     if (ypos3<min) min = ypos3;
  231.     [self lockFocus];
  232.     [self setOpaque: TRUE];
  233.     PSsetlinewidth(0.1);
  234.     if (erase)
  235.         PSsetgray(back_ground);
  236.     else    {
  237.         PSsetgray(marker_gray);
  238.     [ampField setFloatValue: amp_range * (float) (1.0 - ypos2 / frame.size.height)];
  239.     [freqField setFloatValue: freq_range * (float) (xpos / frame.size.width)];
  240.     }
  241.     if (xpos==frame.size.width) xpos -= 1.0;
  242.     PSmoveto(xpos,0.0);
  243.     PSlineto(xpos,min - 5.0);
  244.     PSmoveto(xpos,max + 5.0);
  245.     PSlineto(xpos,frame.size.height);
  246.     PSstroke();
  247.     PSflushgraphics();
  248.     [self unlockFocus];
  249.     return self;
  250. }
  251.  
  252. - printMyPSCode:sender
  253. {
  254.     [[[[[NXApp printInfo] setOrientation:NX_LANDSCAPE andAdjust:YES]
  255.         setHorizCentered:YES]
  256.             setVertCentered:YES]
  257.                 setMarginLeft:0.0
  258.                 right:0.0
  259.                 top:0.0
  260.                 bottom:0.0];
  261.     
  262.     if (back_ground == 0.0/3.0)    {
  263.     NXRunAlertPanel("Too much black ink for the printer.",
  264.     "I'm going to reverse my colors,\
  265.      From now on this view will show reverse.",NULL,NULL,"OK"); 
  266.           back_ground = 3.0/3.0;
  267.       draw_gray = 0.0/3.0;
  268.       marker_gray = 2.0/3.0 ;
  269.            [self clear];
  270.       [self drawSpectrum: last_length array: last_data erase: FALSE];
  271.       [self placeHorizontals: lastHorPos];
  272.       [self placeVerticals: lastVertPos];
  273.       if (last_cursor.x>0 && last_cursor.x<frame.size.width) [self drawCursor: last_cursor erase: FALSE];
  274.     }
  275.     [[self window] printPSCode: sender];    
  276.     return self;      
  277. }
  278.  
  279. @end
  280.